﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;

namespace Microsoft.Office.OneNote
{
    [OneNoteXmlElement("Position")]
    public sealed class OneNoteOutlinePosition :  OneNoteObject, IEquatable<OneNoteOutlinePosition>
    {
        internal static readonly OneNoteProperty XProperty = RegisterProperty("x");
        internal static readonly OneNoteProperty YProperty = RegisterProperty("y");
        internal static readonly OneNoteProperty ZProperty = RegisterProperty("z");

        private static OneNoteProperty RegisterProperty(string name)
        {
            return OneNoteProperty.Register(name, typeof(Double), typeof(OneNoteOutlinePosition));
        }

        internal OneNoteOutlinePosition()
        {
        }

        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public OneNoteOutlinePosition(double x, double y, double z)
        {
            SetValue(XProperty, x);
            SetValue(YProperty, y);
            SetValue(ZProperty, z);
        }

        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public double X
        {
            get { return GetValue<Double>(XProperty); }
        }

        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public double Y
        {
            get { return GetValue<Double>(YProperty); }
        }

        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public double Z
        {
            get { return GetValue<Double>(ZProperty); }
        }

        public override bool Equals(object obj)
        {
            return this.EqualsHelper(obj);
        }

        public bool Equals(OneNoteOutlinePosition other)
        {
            if (ReferenceEquals(other, null))
            {
                return false;
            }

            return
                DoubleHelper.AreClose(X, other.X) &&
                DoubleHelper.AreClose(Y, other.Y) &&
                DoubleHelper.AreClose(Z, other.Z);
        }

        public override int GetHashCode()
        {
            return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode();
        }

        public override string ToString()
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "X={0}, Y={1}, Z={2}", X, Y, Z);
        }
    }
}
